package com.codejoys.monitor.config;

import com.codejoys.monitor.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

// 集中配置安全相关的处理
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    AuthenticationSuccessHandler successHandler;

    @Autowired
    AuthenticationFailureHandler failureHandler;

    @Autowired
    JwtAuthenticationFilter jwtAuthFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                    .loginProcessingUrl("/admin/login") // 发一个post请求，带上用户名和密码
                    .permitAll()    // 登录请求不能拦截
                    .usernameParameter("name")
                    .successHandler(successHandler)   // 登录成功的处理器
                    .failureHandler(failureHandler) // 登录失败的处理器
                .and()
                    .sessionManagement()
                    // 服务器现在不创建session。
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                    .authorizeRequests()
                    .antMatchers("/status/logdown").permitAll()
                    .antMatchers("/admin/register").permitAll()
                    .antMatchers("/configs/**").hasAnyRole("admin", "engineer")
                .anyRequest().authenticated()   // 所有的请求必须先登录
                .and()
                    .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)// 配置认证失败的处理器
                .and()
                    .csrf().disable();      // 关闭csrf（跨站请求伪造）

        // 添加jwt过滤器来处理jwt token
        http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder createPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
